﻿#include "GraphArea.h"
#include "ui_GraphArea.h"
#include "PreWindow3D.h"
#include "BrowserWidget.h"
#include "FITK_Component/FITKWidget/FITKMdiArea.h"
#include "FITK_Kernel/FITKAppFramework/FITKAppFramework.h"
#include "FITK_Kernel/FITKAppFramework/FITKGlobalData.h"
#include "FITK_Kernel/FITKCore/FITKOperatorRepo.h"
#include "FITK_Kernel/FITKCore/FITKActionOperator.h"
#include "FITK_Kernel/FITKAppFramework/FITKMessage.h"

#include <QToolBar>
#include <QPushButton>
#include <QMdiSubWindow>

namespace GUI
{
    GraphArea::GraphArea(QWidget* parent /*= nullptr*/)
        :Core::FITKWidget(parent)
    {
        _ui = new Ui::GraphArea;
        _ui->setupUi(this);

        _toolBar = new QToolBar(this);
        // 工具栏属性
        _toolBar->setMaximumWidth(36);
        _toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
        _toolBar->setIconSize(QSize(24, 24));
        _toolBar->setAllowedAreas(Qt::ToolBarArea::LeftToolBarArea);
        _toolBar->setOrientation(Qt::Orientation::Vertical);
        this->initToolBar();
        _ui->horizontalLayout_3->insertWidget(0, _toolBar);
        //多视区域
        _mdiArea = new Comp::FITKMdiArea(this);
        connect(_mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)), this, SLOT(subWindowActived()));
        _ui->gridLayout->addWidget(_mdiArea);
        //默认初始化添加前处理处理窗口
        BrowserWidget* bw = new BrowserWidget(this);
        PreWindow3D* w3d = new PreWindow3D(this);
        this->addSubWindow(bw);
        this->addSubWindow(w3d);

    }

     
    GraphArea::~GraphArea()
    {
        if (_ui) delete _ui;
    }

    void GraphArea::addSubWindow(GraphAbstractSubWin* subWin)
    {
        if (subWin == nullptr) return;
        //获取按钮
        QPushButton* button = subWin->getPushButton();
        if (button == nullptr || _mdiArea == nullptr) return;
        //追加子窗口
        _mdiArea->addSubWidget(subWin, subWin->windowTitle());
        //显示按钮
        _ui->ButtonLayout->addWidget(button);
    }

    QWidget* GraphArea::getCurrentSubWin()
    {
        //多视口区域当前窗口
        if (_mdiArea == nullptr) return nullptr;
        return _mdiArea->getCurrentWidget();
    }

    QList<GraphAbstractSubWin*> GraphArea::getSubWindowsByType(GUI::GraphAbstractSubWin::SubWinType type)
    {
        QList<GraphAbstractSubWin*> subWindows = {};
        if (_mdiArea == nullptr) {
            return subWindows;
        }

        for (QMdiSubWindow* mdiSubWindow : _mdiArea->subWindowList()) {
            if (mdiSubWindow == nullptr) {
                continue;
            }
            GraphAbstractSubWin* subWin = dynamic_cast<GraphAbstractSubWin*>(mdiSubWindow->widget());
            if (subWin == nullptr) {
                continue;
            }

            if (subWin->getSubWindowType() == type) {
                subWindows.append(subWin);
            }
        }

        return subWindows;
    }

    void GraphArea::activeSubWindow(QWidget* w)
    {
        if (_mdiArea == nullptr) return;
        QMdiSubWindow* sub = _mdiArea->getSubWidget(w);
        if (sub == nullptr)return;
        _mdiArea->setActiveSubWindow(sub);
    }

    GUI::GraphAbstractSubWin* GraphArea::getFirstWindow(GraphAbstractSubWin::SubWinType type)
    {
        if (_mdiArea == nullptr) return nullptr;
        //全部子窗口
        QList<QMdiSubWindow*> subWins = _mdiArea->subWindowList();
        for (QMdiSubWindow* w : subWins)
        {
            if(w == nullptr) continue;
            //子窗口对象
            GraphAbstractSubWin* gw = dynamic_cast<GraphAbstractSubWin*>(_mdiArea->getWidget(w)) ;
            if(gw == nullptr) continue;
            //类型判断
            if (type == gw->getSubWindowType())
                return gw;
        }
        //不存在type类型
        return nullptr;
    }

    void GraphArea::switch2AWindow(GraphAbstractSubWin::SubWinType type)
    {
        //获取窗口
        QWidget* w = this->getFirstWindow(type);
        //设置为当前窗口
        this->activeSubWindow(w);
    }

    void GraphArea::createNewPreWindow()
    {
        PreWindow3D* w3d = new PreWindow3D(this);
        this->addSubWindow(w3d);
    }

    Comp::FITKMdiArea * GraphArea::getMdiArea()
    {
        return _mdiArea;
    }

    void GraphArea::initToolBar()
    {
        QList<QAction*> actions = {};
        //前视角按钮添加
        QAction* action = new QAction(this);
        action->setObjectName("actionViewFront");
        action->setIcon(QIcon(":FITKIcons/icoR_viewFront.svg"));
        action->setToolTip("Front view");
        actions.append(action);
        //后视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewBack");
        action->setIcon(QIcon(":FITKIcons/icoR_viewBack.svg"));
        action->setToolTip("Back view");
        actions.append(action);
        //顶部视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewTop");
        action->setIcon(QIcon(":FITKIcons/icoR_viewTop.svg"));
        action->setToolTip("Top View");
        actions.append(action);
        //底部视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewBottom");
        action->setIcon(QIcon(":FITKIcons/icoR_viewBottom.svg"));
        action->setToolTip("Bottom View");
        actions.append(action);
        //左侧视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewLeft");
        action->setIcon(QIcon(":FITKIcons/icoR_viewLeft.svg"));
        action->setToolTip("Left View");
        actions.append(action);
        //右侧视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewRight");
        action->setIcon(QIcon(":FITKIcons/icoR_viewRight.svg"));
        action->setToolTip("Right View");
        actions.append(action);
        //正视角按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewIso");
        action->setIcon(QIcon(":/ToolBar/toolBar/icoR_viewIso.png"));
        action->setToolTip("Oblique View");
        actions.append(action);
        //自适应按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewAuto");
        action->setIcon(QIcon(":FITKIcons/icoR_autofit.png"));
        action->setToolTip("Restore");
        actions.append(action);
        //保存图片按钮添加
        action = new QAction(this);
        action->setObjectName("actionSaveImage");
        action->setIcon(QIcon(":FITKIcons/icoR_saveimage.png"));
        action->setToolTip("Save Image");
        actions.append(action);
        //平行投影按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewParallel");
        action->setIcon(QIcon(":FITKIcons/icoR_viewParallel.svg"));
        action->setToolTip("Parallel View");
        actions.append(action);
        //正交投影按钮添加
        action = new QAction(this);
        action->setObjectName("actionViewPerspective");
        action->setIcon(QIcon(":FITKIcons/icoR_viewPerspective.svg"));
        action->setToolTip("Perspective View");
        actions.append(action);

        for (QAction* act : actions)
        {
            connect(act, SIGNAL(triggered()), this, SLOT(slotToolBarActionEvent()));
        }

        _toolBar->insertActions(nullptr, actions);
    }

    void GraphArea::subWindowActived()
    {
        GraphAbstractSubWin* win = this->getCurrentWindow<GraphAbstractSubWin>();
        if (win == nullptr && _toolBar != nullptr) return;
        _toolBar->setVisible(win->getSubWindowType() != GraphAbstractSubWin::Browser);
    }

    void GraphArea::slotToolBarActionEvent()
    {
        QObject* obj = this->sender();
        if (obj == nullptr) return;
        QString objName = obj->objectName();
        //从操作器仓库中获取动作事件处理机制操作器
       Core::FITKActionOperator* actOper = Core::FITKOperatorRepo::getInstance()->getOperatorT<Core::FITKActionOperator>(objName);
       if (!actOper)
       {
           //错误提示
           QString error = QString("%1 Operator create failed !").arg(objName);
           AppFrame::FITKMessageError(error);
           return;
       }
       actOper->setEmitter(obj);
       actOper->actionTriggered();
    }

    GraphAbstractSubWin::GraphAbstractSubWin(GraphArea* w /*= nullptr*/)
        :Core::FITKWidget(w),_graphArea(w)
    {
        _pushButton = new QPushButton(this);
        connect(_pushButton, &QPushButton::destroyed, this, [&]() {_pushButton = nullptr; });
        connect(_pushButton, SIGNAL(clicked()), this, SLOT(onButtonClickedSlot()));
    }

    GraphAbstractSubWin::~GraphAbstractSubWin()
    {
        if (_pushButton) delete _pushButton;
    }

    QPushButton* GraphAbstractSubWin::getPushButton()
    {
        return _pushButton;
    }

    GUI::GraphAbstractSubWin::SubWinType GraphAbstractSubWin::getSubWindowType()
    {
        return None;
    }

    void GraphAbstractSubWin::onButtonClickedSlot()
    {
        if (_graphArea == nullptr) return;
        _graphArea->activeSubWindow(this);
    }

}


